#include <unistd.h>
#include <iostream>
#include <queue>
#include <string>
template <typename T>
class BQqueue
{
public:
    BQqueue(size_t cap)
        : _cap(cap)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_condfull,nullptr);
        pthread_cond_init(&_condempty,nullptr);
    }
    void Push(const T &data)
    {
        pthread_mutex_lock(&_mutex);
        while (_q.size() == _cap)
        {
            pthread_cond_wait(&_condfull, &_mutex);
        }
        _q.push(data);
        std::cout << "生产了一个数据:" << data << std::endl;
        pthread_mutex_unlock(&_mutex);
        pthread_cond_signal(&_condempty);
    }
    T pop()
    {
        pthread_mutex_lock(&_mutex);
        while (_q.empty())
        {
            pthread_cond_wait(&_condempty, &_mutex);
        }
        T data = _q.front();
        _q.pop();
        std::cout << "消费了一个数据:" << data << std::endl;
        pthread_mutex_unlock(&_mutex);
        pthread_cond_signal(&_condfull);
        return data;
    }
    ~BQqueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_condfull);
        pthread_cond_destroy(&_condempty);
    }

private:
    std::queue<T> _q; // 队列
    size_t _cap;      // 最大容量
    pthread_mutex_t _mutex;
    pthread_cond_t _condfull;  // 队列不满的条件变量
    pthread_cond_t _condempty; // 队列不空的条件变量
};
int capacity = 3;
BQqueue<int> bq(3);
void *Producer(void *args)
{
    for (int i = 0; i < 10; i++)
    {
        bq.Push(i);
        sleep(1);
    }
    return nullptr;
}

void *Consumer(void *args)
{
    for (int i = 0; i < 10; i++)
    {
        bq.pop();
        sleep(2);
    }
    return nullptr;
}
int main()
{
    pthread_t consumer, producer;
    pthread_create(&consumer, nullptr, Consumer, (void *)"consumer");
    pthread_create(&producer, nullptr, Producer, (void *)"producer");
    pthread_join(consumer, nullptr);
    pthread_join(producer, nullptr);
    return 0;
}
